﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TccServicos.Models;
using TccServicos.Util;

namespace TccServicos.Negocio
{
    public class AnimalNegocio
    {
        string sThread;
        public AnimalNegocio(string thread)
        {
            this.sThread = thread;
        }

        public RetornoAnimal GetAnimal(int? idTipo = null, int? idAnimal = null, int? pagina = null,
            int? itens = null, int? idCadastro = null, int? tipoAnimal = null, int? idGenero = null, 
            int? idRaca = null, int? idPorte = null, int? idUf = null, int? idCidade = null,
            int? idadeMin = null, int? idadeMax = null,
            decimal? pesoMin = null, decimal? pesoMax = null)
        {
            sThread = Util.Util.NextHex(4);
            string nomeFuncao = string.Format("{0} [{1}]", "GetAnimal", sThread);

            try
            {
                Log.GravarLog(string.Format("{0}: id={1}", nomeFuncao, idAnimal.HasValue ? idAnimal.Value.ToString() : "0"));

                using (adoteEntities contexto = new adoteEntities())
                {
                    int abandonado = AnimalTipo.Abandonado.GetHashCode();
                    int doacao = AnimalTipo.Doacao.GetHashCode();

                    var consulta1 = (from t in contexto.CADASTRO_ANIMAL_ABANDONADO.AsNoTracking()
                                     join p in contexto.CADASTRO_PESSOA.AsNoTracking() on t.ID_CADASTRO_PESSOA equals p.ID_CADASTRO_PESSOA
                                     select new Animal
                                     {
                                         id = t.ID_CADASTRO_ABANDONADO,
                                         animalTipoInt = abandonado,
                                         pessoa = new Pessoa()
                                         {
                                             idPessoa = p.ID_CADASTRO_PESSOA,
                                             nome = p.NOME,
                                         },
                                         data = t.DATA.Value,
                                         genero = new Genero()
                                         {
                                             idGenero = 0,
                                             genero = "",
                                         },
                                         raca = new Raca()
                                         {
                                             idRaca = 0,
                                             raca = "",
                                         },
                                         idade = 0,
                                         porte = new Porte()
                                         {
                                             idPorte = 0,
                                             porte = "",
                                         },
                                         peso = 0,
                                         cidade = new Cidade()
                                         {
                                             idCidade = 0,
                                             uf = new Uf()
                                             {
                                                 idUf = 0,
                                                 uf = ""
                                             },
                                             cidade = "",
                                         },
                                         telefone = "",
                                         email = "",
                                         descricao = t.DESCRICAO,
                                         vacinas = "",
                                         nome = "",
                                         latitude = t.LATITUDE,
                                         longitude = t.LONGITUDE,
                                         localizacao = t.LOCALIZACAO,
                                         endereco = t.ENDERECO,
                                         DoadoRecolhido = t.RECOLHIDO,
                                     }).AsQueryable();
                    var consulta2 = (from t in contexto.CADASTRO_ANIMAL.AsNoTracking()
                                     join p in contexto.CADASTRO_PESSOA.AsNoTracking() on t.ID_CADASTRO_PESSOA equals p.ID_CADASTRO_PESSOA
                                     join g in contexto.CADASTRO_GENERO.AsNoTracking() on t.ID_GENERO equals g.ID_GENERO
                                     into gt
                                     from g in gt.DefaultIfEmpty()
                                     join r in contexto.CADASTRO_RACA.AsNoTracking() on t.ID_RACA equals r.ID_RACA
                                     into rt
                                     from r in rt.DefaultIfEmpty()
                                     join po in contexto.CADASTRO_PORTE.AsNoTracking() on t.ID_PORTE equals po.ID_PORTE
                                     into pot
                                     from po in pot.DefaultIfEmpty()
                                     join uf in contexto.CADASTRO_UF.AsNoTracking() on t.ID_UF equals uf.ID_UF
                                     into uft
                                     from uf in uft.DefaultIfEmpty()
                                     join c in contexto.CADASTRO_CIDADE.AsNoTracking() on t.ID_CIDADE equals c.ID_CIDADE
                                     into ct
                                     from c in ct.DefaultIfEmpty()
                                     select new Animal
                                     {
                                         id = t.ID_CADASTRO_ANIMAL,
                                         animalTipoInt = doacao,
                                         pessoa = new Pessoa()
                                         {
                                             idPessoa = p.ID_CADASTRO_PESSOA,
                                             nome = p.NOME,
                                         },
                                         data = t.DATA,
                                         genero = new Genero()
                                         {
                                             idGenero = g != null ? g.ID_GENERO : 0,
                                             genero = g != null ? g.GENERO : null,
                                         },
                                         raca = new Raca()
                                         {
                                             idRaca = r != null ? r.ID_RACA : 0,
                                             raca = r != null ? r.RACA : null,
                                         },
                                         idade = t.IDADE,
                                         porte = new Porte()
                                         {
                                             idPorte = po != null ? po.ID_PORTE : 0,
                                             porte = po != null ? po.PORTE : null,
                                         },
                                         peso = t.PESO,
                                         cidade = new Cidade()
                                         {
                                             idCidade = c != null ? c.ID_CIDADE : 0,
                                             uf = new Uf()
                                             {
                                                 idUf = uf != null ? uf.ID_UF : 0,
                                                 uf = uf != null ? uf.UF : null
                                             },
                                             cidade = c != null ? c.CIDADE : null,
                                         },
                                         telefone = t.TELEFONE,
                                         email = t.EMAIL,
                                         descricao = t.DESCRICAO,
                                         vacinas = t.VACINAS,
                                         nome = t.NOME,
                                         latitude = 0,
                                         longitude = 0,
                                         localizacao = "",
                                         endereco = "",
                                         DoadoRecolhido = t.DOADO,
                                     }).AsQueryable();

                    var consulta = consulta1.Union(consulta2);
                    if (idCadastro.HasValue)
                        consulta = consulta.Where(x => x.pessoa.idPessoa.Equals(idCadastro.Value));
                    if (idTipo.HasValue)
                        consulta = consulta.Where(x => x.animalTipoInt.Equals(idTipo.Value));
                    if (idAnimal.HasValue)
                        consulta = consulta.Where(x => x.id.Equals(idAnimal.Value));
                    if (tipoAnimal.HasValue && tipoAnimal.Value > 0)
                        consulta = consulta.Where(x => x.animalTipoInt == tipoAnimal.Value);
                    if (idGenero.HasValue && idGenero.Value > 0)
                        consulta = consulta.Where(x => x.genero.idGenero == idGenero.Value);
                    if (idRaca.HasValue && idRaca.Value > 0)
                        consulta = consulta.Where(x => x.raca.idRaca == idRaca.Value);
                    if (idPorte.HasValue && idPorte.Value > 0)
                        consulta = consulta.Where(x => x.porte.idPorte == idPorte.Value);
                    if (idUf.HasValue && idUf.Value > 0)
                        consulta = consulta.Where(x => x.cidade.uf.idUf == idUf.Value);
                    if (idCidade.HasValue && idCidade.Value > 0)
                        consulta = consulta.Where(x => x.cidade.idCidade == idCidade.Value);
                    if (idadeMin.HasValue && idadeMin.Value > 0)
                        consulta = consulta.Where(x => x.idade >= idadeMin.Value);
                    if (idadeMax.HasValue && idadeMax.Value > 0)
                        consulta = consulta.Where(x => x.idade <= idadeMax.Value);
                    if (pesoMin.HasValue && pesoMin.Value > 0)
                        consulta = consulta.Where(x => x.peso >= pesoMin.Value);
                    if (pesoMax.HasValue && pesoMax.Value > 0)
                        consulta = consulta.Where(x => x.peso <= pesoMax.Value);

                    consulta = consulta.OrderByDescending(x => x.data);

                    if (pagina.HasValue && itens.HasValue)
                        consulta = consulta.Skip((pagina.Value - 1) * itens.Value).Take(itens.Value);
                    
                    var retorno = consulta.ToList();

                    foreach (var item in retorno)
                    {
                        item.dataFormatada = item.data.ToString("dd/MM/yy HH:mm");
                    }

                    Log.GravarLog(string.Format("{0}: {1}", nomeFuncao, Validacao.consultaComSucesso));

                    return new RetornoAnimal()
                    {
                        lista = retorno,
                    };
                }
            }
            catch (Exception ex)
            {
                Log.GravarLog(string.Format("{0} Erro: {1}", nomeFuncao, ex.ToString()));
                return default(RetornoAnimal);
            }
        }
    }
}
